#include "MovingPlatform.h"
#include "../SGD Wrappers/SGD_Math.h"
#include "Events\CSGD_EventSystem.h"
#include "../SGD Wrappers/CSGD_Direct3D.h"

#include "Camera.h"
#include "Physics.h"
#include "Time.h"


MovingPlatform::MovingPlatform(void)
{
	objectID = "MovingPlatform";
	positionX = 0;
	positionY = 0;

	isReversed = false;
	lastWaypoint = 0;
	isPowered = true;

	velocity.fX = 0;
	velocity.fY = 0;


	BASESPEED = 70;
	canBeGrappled = true;

	//Check point information
	CheckPointIsReversed = false;
	CheckPointIsPowered = false;
	checkpointPosition.x = 0;
	checkpointPosition.y = 0;
	OnlyRevOnce = false;
	ReverseTimer = 0.0f;
	CheckpointLastWayPoint = 0;
}


MovingPlatform::~MovingPlatform(void)
{
}


void MovingPlatform::Update(float deltaTime)
{
	if(!isPowered)
		return;

	//Only ally to reverse in every 2 seconds off a collision
	if( OnlyRevOnce == true )
	{
		ReverseTimer += deltaTime;
		if( ReverseTimer >= 2.0f )
		{
			OnlyRevOnce = false;
			ReverseTimer = 0.0f;
		}
	}


	/*RECT platformRect = {0,0,0,0};

	platformRect.left += (LONG)positionX;
	platformRect.right += (LONG)positionX + 128;
	platformRect.top += (LONG)positionY;
	platformRect.bottom += (LONG)positionY + 32;
	SetHitBox(platformRect);*/


	//If we're at the last waypoint, reverse direction
	if(!isReversed)
	{
		if(lastWaypoint == waypoints.size() - 1)
		{
			isReversed = true;
		}
	}
	else
	{
		if(lastWaypoint == 0)
		{
			isReversed = false;
		}
	}

	//Get vector to next waypoint
	tVector2D curPosVec;
	curPosVec.fX = positionX;
	curPosVec.fY = positionY;

	tVector2D waypointVec;
	if(!isReversed)
	{
		waypointVec.fX = (float) waypoints[lastWaypoint + 1].x;
		waypointVec.fY = (float) waypoints[lastWaypoint + 1].y;
	}					 	   
	else				 	   
	{					 	   
		waypointVec.fX = (float) waypoints[lastWaypoint - 1].x;
		waypointVec.fY = (float) waypoints[lastWaypoint - 1].y;
	}					 
	toWaypoint = waypointVec - curPosVec;

	//set velocity to BASESPEED in the direction we determined above
	velocity = Vector2DNormalize(toWaypoint) * BASESPEED;
	//account for deltaTime
	if(deltaTime != 0.0f)
		velocity *= deltaTime;
	else
	{
		velocity *= 0.0001f;
	}


	//Prepare for next iteration
	if(Vector2DLength(toWaypoint) <= 5.0f)
	{
		if(isReversed)
		{
			--lastWaypoint;
		}
		else
		{
			++lastWaypoint;
		}
	}


	//Update Position
	positionX += velocity.fX;
	positionY += velocity.fY;

	SetHitBox(Physics::UpdateColRect(GetHitBox(), (int)positionX, (int)positionY));

}
void MovingPlatform::Render(void) const
{
	CSGD_TextureManager::GetInstance()->Draw(imageID,(int)(positionX - Camera::GetInstance()->OffsetX() ),(int)(positionY - Camera::GetInstance()->OffsetY() ));
}

void MovingPlatform::HandleCollision(GameObject& other, CollisionInfo& info)
{
	if( other.GetObjectID() != "Static Object") 
	{
		if(info.Side == CollisionSide::BOTTOM)
			other.SetPosY( other.GetPosY() - (info.Overlap.bottom - info.Overlap.top));
		if(info.Side == CollisionSide::TOP)
		{
			other.SetPosY( other.GetPosY() + (info.Overlap.bottom - info.Overlap.top));
			
			//Reverse Direction
			if( OnlyRevOnce == false && other.GetObjectID() == "Player" || other.GetObjectID() == "Radiation Barrel" )
			{
				if( isReversed == false )
				{
					lastWaypoint = lastWaypoint + 1;
				} 
				else
				{
					lastWaypoint = lastWaypoint - 1;
				}
				isReversed = !isReversed;
				OnlyRevOnce = true;
			}
		}
		if(info.Side == CollisionSide::LEFT)
			other.SetPosX( other.GetPosX() + (info.Overlap.right - info.Overlap.left));
		if(info.Side == CollisionSide::RIGHT)
			other.SetPosX( other.GetPosX() - (info.Overlap.right - info.Overlap.left));

		other.SetPosX( other.GetPosX() + velocity.fX );
		other.SetPosY( other.GetPosY() + velocity.fY );

		if(other.GetObjectID() != "Player")
			other.SetHitBox(Physics::UpdateColRect(other.GetHitBox(), (int)(other.GetPosX()), (int)(other.GetPosY())));

	}
}


void MovingPlatform::AddWaypoint(POINT pointToAdd)
{
	waypoints.push_back(pointToAdd);
}


tVector2D MovingPlatform::GetVelocity() const
{
	tVector2D tempVel = velocity;
	tempVel *= 100;
	return tempVel;
}


void MovingPlatform::SetCheckPointData()
{
	checkpointPosition.x = (long)positionX;
	checkpointPosition.y = (long)positionY;
	CheckPointIsReversed = isReversed;
	CheckPointIsPowered = isPowered;
	CheckpointLastWayPoint = lastWaypoint;
}
void MovingPlatform::ResetToCheckPoint()
{
	positionX = (float)checkpointPosition.x;
	positionY = (float)checkpointPosition.y;
	isPowered = CheckPointIsPowered;
	isReversed = CheckPointIsReversed;
	lastWaypoint = CheckpointLastWayPoint;
}

void MovingPlatform::HandleEvent(Event* pEvent)
{
	if (pEvent->GetEventID() == "MachineFixed")
	{
		vector<string>* tags = getSenderTags(pEvent->GetEventID());
		for(unsigned int i = 0; i < tags->size(); ++i)
		{
			if(((GameObject*)pEvent->GetSender())->GetTag() == (*tags)[i])
			{
				SetIsPowered(true);
				break;
			}
		}
	}
	else if (pEvent->GetEventID() == "ButtonActivated")
	{
		vector<string>* tags = getSenderTags(pEvent->GetEventID());
		for(unsigned int i = 0; i < tags->size(); ++i)
		{
			if(((GameObject*)pEvent->GetSender())->GetTag() == (*tags)[i])
			{
				SetIsPowered(true);
				break;
			}
		}
	}
	else if (pEvent->GetEventID() == "ButtonDeactivated")
	{
		vector<string>* tags = getSenderTags(pEvent->GetEventID());
		for(unsigned int i = 0; i < tags->size(); ++i)
		{
			if(((GameObject*)pEvent->GetSender())->GetTag() == (*tags)[i])
			{
				SetIsPowered(false);
				break;
			}
		}
	}
}


void MovingPlatform::SetBaseSpeed(float speed)
{
	this->BASESPEED = speed;
}

unsigned int MovingPlatform::GetWaypointCount(void) const
{
	return waypoints.size();
}

